package com.rtx.wcs.std.handle.ristowcs;

import java.util.Date;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSONObject;
import com.rtx.wcs.std.bean.po.EdiTaskDownLog;
import com.rtx.wcs.std.service.EdiTaskDownLogService;

import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpRequest;


/**
 * 下发WCS任务
 * @author Administrator
 *
 */
public abstract class AbsTaskDownHandle <T> implements TaskDownHandleService{
	
	Logger logger = LoggerFactory.getLogger(AbsTaskDownHandle.class);
	
	ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));
	
	@Autowired
	EdiTaskDownLogService ediTaskDownLogService;

	//处理任务下发
	public void handleTaskDown(String riwwmsrequest,String mappingcode) {
		
		//根据RISWMS下发数据条件 查询将要下发WCS数据
		List<T> list = queryToSendDataByRISWmsCondition(riwwmsrequest);
		
		Assert.isTrue(list.size() >0 ,"没有满足下发条件数据");
		
		//获取接口名称
		String apiname = getapiname(riwwmsrequest);
		
		String wcsresponse = "";
		
		for(T req:list) {
			
			EdiTaskDownLog log = null;
			try {
				//将数据转换将要下发WCS报文
				JSONObject ediRequest = converWcsRequest(req, mappingcode);
				
				//日志记录实体类
				log = createEdiTaskDownLog(riwwmsrequest,req,ediRequest,mappingcode);
				
				//请求wcs
				wcsresponse =  callWcsAPI(apiname,ediRequest,log,mappingcode);
				
				updStatus(req,wcsresponse,mappingcode);
				
			} catch (Exception e) {
				logger.error("下发WCS任务",e);
				throw new RuntimeException(e.getMessage());
			}finally {
				insertLogs(log);
			}
		}
		

	}
	
	
	protected void insertLogs(EdiTaskDownLog log) {
		try {
			pool.execute(()->{
				ediTaskDownLogService.insertLog("ris_edi", log);
	        });
			
		} catch (Exception e) {
			logger.error("",e);
		}
	};
	
	
	
	/**
	 * 生成日志实体类
	 * @return
	 */
	protected EdiTaskDownLog createEdiTaskDownLog(String riswmsrequest,T req,JSONObject edirequest,String mapingcode) {
		EdiTaskDownLog log = new EdiTaskDownLog();
		log.setApiname("WMS->WCS任务下发");
		
		log.setRiswmsrequest(riswmsrequest);
		log.setRiswmsrequesturl("/edi/wcs/task/down");
		
		log.setEdirequest(edirequest.toString());
		
		log.setEdirequesturl(getEdiRequestURL(mapingcode));
		
		log.setAdddate(new Date());
		
		try {
			//将实体类信息映射到日志表
			mappingReqToLog(req,log);
		} catch (Exception e) {
			logger.error("",e);
		}
		
		return log;
	};
	
	/**
	 * 更新状态
	 * @param data
	 */
	protected abstract void updStatus(T data,String wcsresponse,String mappingcode);
	
	/**
	 * 将实体类信息映射到日志表
	 * @param data
	 */
	protected abstract void mappingReqToLog(T data,EdiTaskDownLog log);
	
	
	/**
	 * 根据RISWMS下发数据条件 查询将要下发WCS数据
	 * @param request
	 * @return
	 */
	protected abstract List<T> queryToSendDataByRISWmsCondition(String request);
	
	/**
	 * 将数据转换将要下发WCS报文
	 * @param t
	 * @return
	 */
	protected abstract JSONObject converWcsRequest(T t,String mappingcode);
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	protected abstract String getapiname(String request);
	
	/**
	 * 请求WCS接口
	 * @param apiname
	 * @param request
	 * @return
	 */
	protected String callWcsAPI(String apiname,JSONObject request,EdiTaskDownLog log,String apimappingcode) {
		String uuid = UUID.randomUUID().toString();
		String	result = "";
		try {
			String requestURL = getEdiRequestURL(apimappingcode);
			String requestStr = request.toJSONString();
			log.setEdirequest(requestStr);
			log.setEdirequesturl(requestURL);
			logger.info("uid-{}-url-{}-{}-请求报文-{}",uuid,requestURL,apiname,requestStr);
			result = HttpRequest
					.post(requestURL)
					.body(request.toJSONString())
					.timeout(30000)
					.execute()
					.body();
			log.setWcsresponse(result);
			logger.info("uid-{}-url-{}-{}-响应报文-{}",uuid,requestURL,apiname,result);
		} catch (Exception e) {
			logger.error("请求-"+apiname+"-异常",e);
		}

		return result;
	};
	
	/**
	 * 请求url
	 * @return
	 */
	protected abstract String getEdiRequestURL(String mappingcode);
}
